#include "sdk.h"
#include "filegroupsandmasks.h"

FilesGroupsAndMasks::FilesGroupsAndMasks() {
  Load();
  if( m_Groups.GetCount() == 0 ) {
    SetDefault( false );
  }
}

FilesGroupsAndMasks::FilesGroupsAndMasks( const FilesGroupsAndMasks& rhs ) {
  CopyFrom( rhs );
}

FilesGroupsAndMasks::~FilesGroupsAndMasks() {
  Save();
  Clear();
}

void FilesGroupsAndMasks::CopyFrom( const FilesGroupsAndMasks& rhs ) {
  Clear();
  for( unsigned int i = 0; i < rhs.m_Groups.GetCount(); ++i ) {
    FileGroups* fg = new FileGroups;
    FileGroups* otherfg = rhs.m_Groups[i];
    fg->groupName = otherfg->groupName;
    fg->fileMasks = otherfg->fileMasks;
    m_Groups.Add( fg );
  }
}

void FilesGroupsAndMasks::SetDefault( bool do_clear ) {
  if( do_clear ) {
    Clear();
  }
  unsigned int group;
  group = AddGroup( _T( "源文件" ) );
  SetFileMasks( group, _T( "*.c;*.cpp;*.cc;*.cxx" ) );
  group = AddGroup( _T( "头文件" ) );
  SetFileMasks( group, _T( "*.h;*.hpp;*.hh;*.hxx" ) );
  group = AddGroup( _T( "汇编代码" ) );
  SetFileMasks( group, _T( "*.asm;*.s;*.ss;*.s62" ) );
  group = AddGroup( _T( "资源" ) );
  SetFileMasks( group, _T( "*.xrc;*.wxs;*.png;*.jpg" ) );
  group = AddGroup( _T( "内嵌脚本" ) );
  SetFileMasks( group, _T( "*.script" ) );
  group = AddGroup( _T( "脚本" ) );
  SetFileMasks( group, _T( "*.lua;*.sh" ) );
  group = AddGroup( _T( "网页" ) );
  SetFileMasks( group, _T( "*.html;*.php" ) );
  group = AddGroup( _T( "构建脚本" ) );
  SetFileMasks( group, _T( "*.Makefile" ) );
  group = AddGroup( _T( "ico" ) );
  SetFileMasks( group, _T( "*.xpm" ) );
}

void FilesGroupsAndMasks::Load() {
  Clear();
  ConfigManager* conf = Manager::Get()->GetConfigManager( _T( "project_manager" ) );
  wxArrayString list = conf->EnumerateSubPaths( _T( "/file_groups" ) );
  for( unsigned int i = 0; i < list.GetCount(); ++i ) {
    wxString key = _T( "/file_groups/" ) + list[i];
    unsigned int group = AddGroup( conf->Read( key + _T( "/name" ) ) );
    SetFileMasks( group, conf->Read( key + _T( "/mask" ) ) );
  }
}

void FilesGroupsAndMasks::Save() {
  ConfigManager* conf = Manager::Get()->GetConfigManager( _T( "project_manager" ) );
  conf->DeleteSubPath( _T( "/file_groups" ) );
  for( unsigned int i = 0; i < m_Groups.GetCount(); ++i ) {
    FileGroups* fg = m_Groups[i];
    wxString key;
    key << _T( "/file_groups/group" ) << F( _T( "%u" ), i ) << _T( "/name" );
    conf->Write( key, fg->groupName );
    key.Clear();
    key << _T( "/file_groups/group" ) << F( _T( "%u" ), i ) << _T( "/mask" );
    conf->Write( key, GetStringFromArray( MakeUniqueArray( fg->fileMasks, false ), _T( ";" ) ) );
  }
}

void FilesGroupsAndMasks::Clear() {
  for( unsigned int i = 0; i < m_Groups.GetCount(); ++i ) {
    FileGroups* fg = m_Groups[i];
    if( fg ) {
      delete fg;
    }
  }
  m_Groups.Clear();
}

unsigned int FilesGroupsAndMasks::AddGroup( const wxString& name ) {
  FileGroups* fg = new FileGroups;
  fg->groupName = name;
  m_Groups.Add( fg );
  return m_Groups.GetCount() - 1;
}

void FilesGroupsAndMasks::RenameGroup( unsigned int group, const wxString& newName ) {
  if( group >= m_Groups.GetCount() ) {
    return;
  }
  FileGroups* fg = m_Groups[group];
  fg->groupName = newName;
}

void FilesGroupsAndMasks::DeleteGroup( unsigned int group ) {
  if( group >= m_Groups.GetCount() ) {
    return;
  }
  FileGroups* fg = m_Groups[group];
  delete fg;
  m_Groups.Remove( fg );
}

void FilesGroupsAndMasks::SetFileMasks( unsigned int group, const wxString& masks ) {
  if( group >= m_Groups.GetCount() ) {
    return;
  }
  FileGroups* fg = m_Groups[group];
  fg->fileMasks = MakeUniqueArray( GetArrayFromString( masks, _T( ";" ) ), false );
}

unsigned int FilesGroupsAndMasks::GetGroupsCount() const {
  return m_Groups.GetCount();
}

wxString FilesGroupsAndMasks::GetGroupName( unsigned int group ) const {
  if( group >= m_Groups.GetCount() ) {
    return wxEmptyString;
  }
  const FileGroups* fg = m_Groups[group];
  return fg->groupName;
}

wxString FilesGroupsAndMasks::GetFileMasks( unsigned int group ) const {
  if( group >= m_Groups.GetCount() ) {
    return wxEmptyString;
  }
  const FileGroups* fg = m_Groups[group];
  return GetStringFromArray( MakeUniqueArray( fg->fileMasks, false ) );
}

bool FilesGroupsAndMasks::MatchesMask( const wxString& ext, unsigned int group ) const {
  if( ext.IsEmpty() || group >= m_Groups.GetCount() ) {
    return false;
  }
  const FileGroups* fg = m_Groups[group];
  for( unsigned int i = 0; i < fg->fileMasks.GetCount(); ++i ) {
    if( ext.Lower().Matches( fg->fileMasks[i].Lower() ) ) {
      return true;
    }
  }
  return false;
}
